
<?php
namespace app\server\controller;

use Workerman\Worker;
use think\facade\Db;

class TcpServer
{
    public function start()
    {
        // 创建TCP服务器监听808端口
        $tcpWorker = new Worker('tcp://0.0.0.0:8080');
        $tcpWorker->count = 4;
        
        $tcpWorker->onConnect = function ($connection) {
            echo "New connection from " . $connection->getRemoteIp() . "\n";
        };
        
        $tcpWorker->onMessage = function ($connection, $data) {
            try {
                $JT808 = new JT808();
                $data16Arrays = $JT808->getTo16Bytes($data);
                
                foreach ($data16Arrays as $data16Array) {
                $messageId = $JT808->getMessageIdNumber($data16Array);
                $equipmentNumber = $JT808->getEquipmentNumber($data16Array);
                
                switch ($messageId) {
                    case '0100': // 终端注册
                        $this->handleRegister($connection, $JT808, $data16Array, $equipmentNumber);
                        break;
                    case '0002': // 心跳
                        $this->handleHeartbeat($connection, $JT808, $equipmentNumber);
                        break;
                    case '0200': // 位置信息上报
                        $this->handleLocation($connection, $JT808, $data16Array, $equipmentNumber);
                        break;
                    case '0102': // 终端鉴权
                        $this->handleAuth($connection, $JT808, $data16Array, $equipmentNumber);
                        break;
                    default:
                        echo "Unknown message type: {$messageId}\n";
                }
            }
            } catch (\Exception $e) {
                echo "Error processing message: " . $e->getMessage() . "\n";
            }
        };
        
        $tcpWorker->onClose = function ($connection) {
            echo "Connection closed\n";
        };
        
        Worker::runAll();
    }

    /**
     * 处理终端注册
     */
    private function handleRegister($connection, $JT808, $data, $equipmentNumber)
    {
        // 验证终端信息
        $terminalInfo = Db::name('terminals')
            ->where('equipment_number', $equipmentNumber)
            ->find();
            
        if ($terminalInfo) {
            $response = $JT808->packRegisterResponse($equipmentNumber, 0, '123456');
            
            // 记录注册日志
            Db::name('terminal_logs')->insert([
                'terminal_id' => $terminalInfo['id'],
                'message_type' => 'register',
                'content' => '终端注册成功',
                'create_time' => time()
            ]);
        } else {
            $response = $JT808->packRegisterResponse($equipmentNumber, 1);
        }
        
        $connection->send($response);
    }

    /**
     * 处理心跳
     */
    private function handleHeartbeat($connection, $JT808, $equipmentNumber)
    {
        // 更新终端在线状态
        Db::name('terminals')
            ->where('equipment_number', $equipmentNumber)
            ->update([
                'last_heartbeat' => time(),
                'status' => 1
            ]);
            
        echo "Heartbeat from {$equipmentNumber}\n";
    }

    /**
     * 处理位置信息上报
     */
    private function handleLocation($connection, $JT808, $data, $equipmentNumber)
    {
        // 解析位置信息
        $latitude = $JT808->getLatitude($data, 21, 'f');
        $longitude = $JT808->getLongitude($data, 25, 'f');
        $speed = $JT808->getSpeed($data, 31);
        $direction = $JT808->getDirection($data, 33);
        $datetime = $JT808->getDatetime($data, 35);
        
        // 存储位置数据
        Db::name('terminal_locations')->insert([
            'terminal_id' => $equipmentNumber,
            'latitude' => $latitude,
            'longitude' => $longitude,
            'speed' => $speed,
            'direction' => $direction,
            'location_time' => $datetime,
            'create_time' => time()
        ]);
        
        echo "Location update from {$equipmentNumber}: {$latitude}, {$longitude}\n";
    }

    /**
     * 处理终端鉴权
     */
    private function handleAuth($connection, $JT808, $data, $equipmentNumber)
    {
        // 验证鉴权码
        $authResult = $this->verifyAuthCode($data, $equipmentNumber);
        
        if ($authResult) {
            echo "Auth success for {$equipmentNumber}\n";
        } else {
            echo "Auth failed for {$equipmentNumber}\n";
        }
    }
    
    private function verifyAuthCode($data, $equipmentNumber)
    {
        // 鉴权验证逻辑
        return true;
    }
}
